package ar.uba.tleng.g99.expregs;

import java.util.Set;

import ar.uba.tleng.g99.expregs.automata.AutomataD;
import ar.uba.tleng.g99.expregs.automata.AutomataND;
import ar.uba.tleng.g99.expregs.automata.NodeD;
import ar.uba.tleng.g99.expregs.parser.Expr;
import ar.uba.tleng.g99.expregs.parser.G99Parser;

/**
 * Matchea cadenas segun un automata deterministico.
 * 
 * @author g99
 */
public class G99Matcher {

	/**
	 * El AFD.
	 */
	private AutomataD afd;

	/**
	 * Crea un nuevo G99Matcher con la regexp dada.
	 * 
	 * @param sigma el alfabeto.
	 * @param regexp la regexp.
	 * @throws G99RegexpException si la expresion esta mal formada.
	 */
	public G99Matcher(Set<Character> sigma, String regexp) throws G99RegexpException {
		G99Parser parser = new G99Parser();
		Expr expr = parser.parse(regexp);
		if (expr == null) {
			throw new G99RegexpException("Malformed regexp: " + regexp);
		}
		AutomataND afnd = AutomataND.fromExpr(sigma, expr);
		this.afd = AutomataD.fromAFND(afnd);
	}

	/**
	 * Devuelve true iff la cadena dada matchea.
	 * 
	 * @param string
	 *            la cadena.
	 * @return true iff la cadena dada matchea.
	 */
	public boolean match(String string) {
		NodeD node = afd.getInitialNode();
		for (int i = 0; i < string.length(); i++) {
			if (node == null) {
				return false;
			}
			Character c = string.charAt(i);
			node = node.move(c);
		}
		if (node == null) {
			return false;
		}
		return afd.getFinalNodes().contains(node);
	}

}
